﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using TFSWorkflowControl.Common;
using System.Reflection;

namespace TFSWorkflowControl.TeamExplorer.WPF
{

    public partial class WIStateControl
    {
        private const string IterationPathReferenceDate = "System.IterationPath";
        private const string StateReferenceName = "System.State";
        private const string ReasonReferenceName = "System.Reason";


        private WorkItem _currentWorkItem;
        private string _currentReferenceName;       

        public Option OptionData
        {
            get;
            set;

        }

        public WorkItem WorkItem
        {
            get
            {
                return _currentWorkItem;
            }
            set
            {
                if (_currentWorkItem != value)
                {
                    _currentWorkItem = value;                   
                }
            }
        }

        public WIStateControl()
        {
            InitializeComponent();
            var assembly = Assembly.GetAssembly(typeof(WIStateControl));
            var assemblyName = new AssemblyName(assembly.FullName);
            versionLabel.Text = assemblyName.Version.ToString();            
        }

        private IList<GroupNameAndReference> GetAvailableGroupsFromWorkItem(WorkItem wi, List<string> fieldToIgnoreList)
        {
            if (wi == null)
                throw new ArgumentNullException("wi", "wi is null.");
            if (fieldToIgnoreList == null)
                throw new ArgumentNullException("fieldToIgnoreList", "fieldToIgnoreList is null.");


            List<GroupNameAndReference> result = new List<GroupNameAndReference>();


            var iterationField = wi.GetField(IterationPathReferenceDate);


            result.Add(new GroupNameAndReference() { Name = iterationField.Name, Reference = iterationField.ReferenceName });

            var q = (from field in wi.Fields.Cast<Field>()
                     where
                        !fieldToIgnoreList.Contains(field.ReferenceName) && 
                        field.HasAllowedValuesList &&
                        String.Compare(field.ReferenceName, IterationPathReferenceDate, false) != 0 &&
                        field.IsEditable &&
                        String.Compare(field.ReferenceName, StateReferenceName, false) != 0 &&
                        String.Compare(field.ReferenceName, ReasonReferenceName, false) != 0 &&
                        !field.IsComputed
                     orderby field.Name
                     select new GroupNameAndReference() { Name = field.Name, Reference = field.ReferenceName });

            result.AddRange(q);
            return result;
        }


        internal StateInfoCollection States
        {
            get
            {
                var odp = Resources["stateCollection"] as ObjectDataProvider;
                return odp.ObjectInstance as StateInfoCollection;
            }
        }


        public void Refresh()
        {
            if (_currentWorkItem == null)
            {
                this.Visibility = Visibility.Hidden;
                return;
            }

            Visibility = Visibility.Visible;

            var items = GetAvailableGroupsFromWorkItem(_currentWorkItem, OptionData.FieldToIgnoreList);

            cbGroup.ItemsSource = items;

            if (!items.Any(item => item.Reference == _currentReferenceName))
            {
                if (items.Any(item => item.Reference == OptionData.DefaultField))
                {
                    _currentReferenceName = OptionData.DefaultField;
                }
                else
                {
                    _currentReferenceName = IterationPathReferenceDate;
                }
            }            

            cbGroup.SelectedValue = items.First(item => item.Reference == _currentReferenceName);

            States.FillFromWorkItem(_currentWorkItem, _currentReferenceName);
        }
        

        private void cbGroup_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count == 0)
            {
                return;
            }
            var selectedGroup = e.AddedItems[0] as GroupNameAndReference;

            if (selectedGroup == null)
            {
                return;
            }

            if (selectedGroup.Reference == _currentReferenceName)
            {
                return;
            }

            _currentReferenceName = selectedGroup.Reference;

            States.FillFromWorkItem(_currentWorkItem, _currentReferenceName);
        }


        public class GroupNameAndReference
        {
            public string Name { get; set; }
            public string Reference { get; set; }
        }

    }
}